import axios, { AxiosInstance, AxiosResponse } from 'axios'
import { message } from 'antd'
import type { RootState } from '@/store'
import { getApiBaseUrl, getRequestTimeout } from '@/config'

/**
 * HTTP请求服务
 * 
 * 存储策略说明：
 * - 所有localStorage键都使用 'core-admin' 前缀
 * - 统一管理方式：@/constants/storage.ts
 * - Redux persist自动处理token持久化
 * - 详细配置请参考：@/store/index.ts
 */

// 延迟导入，避免循环依赖
let store: any = null

// 动态获取 store 实例
const getStore = async () => {
  if (!store) {
    const storeModule = await import('@/store')
    store = storeModule.store
  }
  return store
}

// 获取 token 的函数
const getToken = async () => {
  const currentStore = await getStore()
  const state: RootState = currentStore.getState()
  return state.auth.token
}

// 获取 refreshToken 的函数
const getRefreshToken = async () => {
  const currentStore = await getStore()
  const state: RootState = currentStore.getState()
  return state.auth.refreshToken
}

// 设置 token 的函数
const setTokens = async (accessToken: string, refreshToken: string) => {
  const currentStore = await getStore()
  // 动态导入 action
  const authSliceModule = await import('@/store/slices/authSlice')
  currentStore.dispatch(authSliceModule.setTokens({ token: accessToken, refreshToken }))
}

// 清除 token 的函数
const clearTokens = async () => {
  const currentStore = await getStore()
  // 动态导入 action
  const authSliceModule = await import('@/store/slices/authSlice')
  currentStore.dispatch(authSliceModule.clearAuth())
}

// 创建axios实例
const request: AxiosInstance = axios.create({
  baseURL: getApiBaseUrl(),
  timeout: getRequestTimeout(),
  headers: {
    'Content-Type': 'application/json',
  },
})

// 用于标记是否正在刷新令牌
let isRefreshing = false
// 存储待重试的请求
let failedQueue: Array<{
  resolve: (value?: any) => void
  reject: (reason?: any) => void
}> = []

// 处理队列中的请求
const processQueue = (error: any, token: string | null = null) => {
  failedQueue.forEach(({ resolve, reject }) => {
    if (error) {
      reject(error)
    } else {
      resolve(token)
    }
  })
  
  failedQueue = []
}

// 请求拦截器
request.interceptors.request.use(
  async (config) => {
    // 添加认证token
    const token = await getToken()
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<any, any>) => {
    const { data } = response
    // 成功响应直接返回data中的数据部分
    if (data.code === 200) {
      // 修改response.data，保持AxiosResponse结构
      response.data = {
        code: data.code,
        data: data.data,
        message: data.message,
        timestamp: data.timestamp || Date.now()
      }
      return response
    }
    
    // 业务错误处理
    message.error(data.message || '请求失败').then()
    return Promise.reject(new Error(data.message || '请求失败'))
  },
  async (error) => {
    // 已移除开发环境下的 console 错误日志输出，避免控制台噪音
    const originalRequest = error.config
    
    // HTTP错误处理
    if (error.response) {
      const { status, data } = error.response
      
      // 处理401未授权错误，尝试刷新令牌
      if (status === 401 && !originalRequest._retry) {
        if (isRefreshing) {
          // 如果正在刷新令牌，将请求加入队列
          return new Promise((resolve, reject) => {
            failedQueue.push({ resolve, reject })
          }).then(token => {
            originalRequest.headers.Authorization = `Bearer ${token}`
            return request(originalRequest)
          }).catch(err => {
            return Promise.reject(err)
          })
        }

        originalRequest._retry = true
        isRefreshing = true

        const refreshToken = await getRefreshToken()
        
        if (refreshToken) {
          try {
            // 直接调用刷新令牌API，避免循环依赖
            const refreshResponse = await axios.post(`${getApiBaseUrl()}/auth/refresh`, {
              refreshToken: refreshToken
            })
            
            const { data } = refreshResponse
            if (data.code === 200) {
              const { accessToken, refreshToken: newRefreshToken } = data.data
              
              // 更新Redux存储的令牌
              await setTokens(accessToken, newRefreshToken)
              
              // 更新请求头
              originalRequest.headers.Authorization = `Bearer ${accessToken}`
              
              // 处理队列中的请求
              processQueue(null, accessToken)
              
              // 重试原始请求
              return request(originalRequest)
            } else {
              throw new Error(data.message || 'Token刷新失败')
            }
          } catch (refreshError) {
            // 刷新令牌失败，清除Redux存储并跳转到登录页
            processQueue(refreshError, null)
            await clearTokens()
            message.error('登录已过期，请重新登录')
            window.location.href = '/login'
            return Promise.reject(refreshError)
          } finally {
            isRefreshing = false
          }
        } else {
          // 没有刷新令牌，直接跳转到登录页
          await clearTokens()
          message.error('未授权，请重新登录')
          window.location.href = '/login'
          return Promise.reject(error)
        }
      }
      
      // 处理其他HTTP错误
      switch (status) {
        case 403:
          message.error('拒绝访问')
          break
        case 404:
          message.error('请求地址不存在')
          break
        case 500:
          message.error('服务器内部错误')
          break
        default:
          message.error(data?.message || '请求失败')
      }
    } else if (error.request) {
      message.error('网络错误，请检查网络连接')
    } else {
      message.error('请求配置错误')
    }

    return Promise.reject(error)
  }
)

// 通用响应接口
interface ApiResponse<T = any> {
  code: number
  data: T
  message: string
  timestamp: number
}

/**
 * GET 请求封装
 * @param url 请求地址
 * @param params 查询参数
 * @returns Promise<ApiResponse<T>>
 */
export const get = <T = any>(url: string, params?: any): Promise<ApiResponse<T>> => {
  return request.get<ApiResponse<T>>(url, { params }).then(res => res.data)
}

/**
 * POST 请求封装
 * @param url 请求地址
 * @param data 请求数据
 * @returns Promise<ApiResponse<T>>
 */
export const post = <T = any>(url: string, data?: any): Promise<ApiResponse<T>> => {
  return request.post<ApiResponse<T>>(url, data).then(res => res.data)
}

/**
 * PUT 请求封装
 * @param url 请求地址
 * @param data 请求数据
 * @returns Promise<ApiResponse<T>>
 */
export const put = <T = any>(url: string, data?: any): Promise<ApiResponse<T>> => {
  return request.put<ApiResponse<T>>(url, data).then(res => res.data)
}

/**
 * DELETE 请求封装
 * @param url 请求地址
 * @param params 查询参数
 * @returns Promise<ApiResponse<T>>
 */
export const del = <T = any>(url: string, params?: any): Promise<ApiResponse<T>> => {
  return request.delete<ApiResponse<T>>(url, { params }).then(res => res.data)
}

/**
 * PATCH 请求封装
 * @param url 请求地址
 * @param data 请求数据
 * @returns Promise<ApiResponse<T>>
 */
export const patch = <T = any>(url: string, data?: any): Promise<ApiResponse<T>> => {
  return request.patch<ApiResponse<T>>(url, data).then(res => res.data)
}

// 导出原始 axios 实例，用于特殊需求
export default request
